//
// Created by 王筱童 on 2022/5/9.
//

#ifndef TINY_REDIS_SERVER_CMAKE_REDIS_SERVER_H
#define TINY_REDIS_SERVER_CMAKE_REDIS_SERVER_H
#include <asio.hpp>
#include <memory>
#include <vector>
#include <string>
#include <unordered_map>
#include <thread>
#include "redis_connection.h"
#include "command_manager.h"
#include "save_maneger.h"
#include "database.h"
#include "slave_manager.h"
#include <array>
#include "senti_manager.h"
class redis_server {
private:

    friend class redis_connection;
    friend class command_manager;
    friend class save_maneger;
    friend class slave_manager;
    friend class senti_manager;

    typedef std::unique_ptr<redis_connection> conn_ptr;

    asio::io_context io_context;
    asio::io_context::work io_worker;


    asio::io_context run_context;
    asio::io_context::work run_worker;
    std::thread run_thread;

    asio::io_context timer_context;
    asio::io_context::work timer_worker;
    std::thread timer_thread;

    asio::ip::tcp::acceptor acceptor;
    std::unordered_map<std::uint64_t,conn_ptr> connections;
    std::uint64_t conn_index=0;

    command_manager cmd_run;

    constexpr static std::size_t db_nums=16;
    std::array<database,db_nums> dbs;

    save_maneger save;
    slave_manager slaves;
    senti_manager senti;
    redis_connection *master= nullptr;
    bool before_reload= true;
    asio::awaitable<void> listen();
    void register_timer();
    void close_conn(std::size_t index);
    std::string exec_command(const std::string &command,const std::vector<std::string>& args,std::size_t);
    asio::awaitable<void> init();
public:
    redis_server(const std::string& ip,std::uint16_t port);
    void run();
};


#endif //TINY_REDIS_SERVER_CMAKE_REDIS_SERVER_H
